package com.example.spring.code.a05;

import org.mybatis.spring.mapper.MapperFactoryBean;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.context.annotation.AnnotationBeanNameGenerator;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.type.ClassMetadata;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;

import java.io.IOException;
import java.util.Arrays;

public class MapperPostProcessor implements BeanDefinitionRegistryPostProcessor {
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        try {
            // 创建资源解析器，用于匹配类路径下的资源文件
            PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
            // 获取指定包路径下的所有 .class 文件（mapper 包中的接口）
            Resource[] resources = resolver.getResources("classpath:com/example/spring/code/a05/mapper/**/*.class");
            // 创建元数据读取工厂，用于读取类的结构信息
            CachingMetadataReaderFactory factory = new CachingMetadataReaderFactory();
            // 创建一个 Bean 名称生成器，默认使用类名首字母小写作为 bean 名称
            AnnotationBeanNameGenerator generator = new AnnotationBeanNameGenerator();
            // 遍历所有资源文件
            Arrays.stream(resources).forEach(resource -> {
                try {
                    // 通过 MetadataReader 读取类的元数据
                    MetadataReader reader = factory.getMetadataReader(resource);
                    // 获取类的基本信息（如是否是接口、类名等）
                    ClassMetadata classMetadata = reader.getClassMetadata();
                    // 只处理接口类型的类
                    if (classMetadata.isInterface()) {
                        // 构建 MapperFactoryBean 的 BeanDefinition
                        // MapperFactoryBean 是 MyBatis-Spring 提供的工厂 Bean，用于创建 Mapper 实例
                        AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(MapperFactoryBean.class)
                                // 设置构造函数参数：Mapper 接口的全限定类名
                                .addConstructorArgValue(classMetadata.getClassName())
                                // 设置自动装配模式为按类型注入
                                .setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE)
                                .getBeanDefinition();
                        // 构建一个普通的 BeanDefinition，用于生成 Bean 名称
                        AbstractBeanDefinition beanDefinition1 = BeanDefinitionBuilder.genericBeanDefinition(classMetadata.getClassName()).getBeanDefinition();
                        // 使用 AnnotationBeanNameGenerator 生成 Bean 名称（默认规则：首字母小写）
                        String name = generator.generateBeanName(beanDefinition1, registry);
                        // 将 MapperFactoryBean 注册为 Bean，名称为接口对应的驼峰命名
                        registry.registerBeanDefinition(name, beanDefinition);
                    }
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            });
        } catch (IOException e) {
            throw new RuntimeException(e);
        }


    }
}
